Функции


In [1]:
# функции
def product(*args):
    result = 1
    for arg in args:
        result *= arg
    return result
print (product(3,4,6))


72

In [3]:
def product(*args, power = 2):
    result = 1
    for arg in args:
        result *= arg**power
    return result
print (product(3,4,6))


5184

In [5]:
# Задача. Найти сумму длин входящих слов. Количество не определено. 
# Должны учитываться все слова, за исключением слов, который вхдят в другой список - стоп лист.
def countLetters(*args, stopWords = []):


  File "<ipython-input-5-268ee695c1f9>", line 3
    def countLetters(*args, stopWords = []):
                                            ^
SyntaxError: unexpected EOF while parsing

In [ ]:
# Задача1. Проверить - можно ли из набора букв сделать полиндром, обязательно нужно воспользоваться всеми буквами.
# Полиндром, это слово которой вперед и назад читается одинаково

# Задача2. А как проверить, что слово полиндром?

In [ ]:
# Задача. Написать функцию, которая из исходного списка, вернет только четные числа в виде отельного списка

In [10]:
import random
random.randint(2, 8) # генерация случайных чисел

# Напишите функцию, которая на вход получает диапозон и количество чисел. А нужно вернуть случайные числа в этом диапозоне, в заданном количестве
# но без повторения


Out[10]:
4

In [ ]:
# Написать функцию определения простоты числа

In [ ]:

Классы

Полиморфизм в разных объектах одна и та же операция может выполнять различные функции. Слово «полиморфизм» имеет греческую природу и означает «имеющий многие формы». Простым примером полиморфизма может служить функция count(), выполняющая одинаковое действие для различных типов обьектов: 'abc'.count('a') и [1, 2, 'a'].count('a'). Оператор плюс полиморфичен при сложении чисел и при сложении строк.

Инкапсуляция: можно скрыть ненужные внутренние подробности работы объекта от окружающего мира. Это второй основной принцип абстракции. Он основан на использовании атрибутов внутри класса. Атрибуты могут иметь различные состояния в промежутках между вызовами методов класса, вследствие чего сам объект данного класса также получает различные состояния — state.

Наследование: можно создавать специализированные классы на основе базовых. Это позволяет нам избегать написания повторного кода.


In [1]:
# объявление класса 
class Simple:
    'Простой класс'
    var = 87
    def f(x):
        return 'Hello world'

In [2]:
# Создание экземпляра класса похоже на то, как будто мы делаем вызов функций:
smpl = Simple()
Объект класса и инстанс класса — это два разных объекта. Первый генерируется на этапе объявления класса, второй — при вызове имени класса. Объект класса может быть один, инстансов класса может быть сколько угодно.
Будет создан пустой объект smpl. Если мы хотим, чтобы при создании выполнялись какие-то действия, нужно определить конструктор, который будет вызываться автоматически:
Обычно первый аргумент в имени метода — self. Как говорит автор языка Гвидо Ван Россум, это не более чем соглашение: имя self не имеет абсолютно никакого специального значения.

In [11]:
class Simple:
    'Простой класс'
    var = 87
    def f(x):
        return 'Hello world'
    
    def __init__(self, count, str):
        self.list = []
        self.count = count
        self.str = str

In [12]:
s = Simple(1,'22')

In [14]:
print (s.count, s.str, s.list)


1 22 []

Инкапсуляция

Атрибут данных можно сделать приватным (private) — т.е. недоступным снаружи — для этого слева нужно поставить два символа подчеркивания:

In [25]:
class Simple:
    u'Простой класс с приватным атрибутом'
    __private_attr = 10
    def __init__(self, count, str):
        self.__private_attr = 20
        print (self.__private_attr)

s = Simple(1,'22')
print (s.__private_attr)


20
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-25-c2a14938a4ae> in <module>()
      7 
      8 s = Simple(1,'22')
----> 9 print (s.__private_attr)

AttributeError: 'Simple' object has no attribute '__private_attr'

In [21]:
# Методы необязательно определять внутри тела класса:
def method_for_simple(self, x, y):
    return x + y

class Simple:
    f = method_for_simple
 
s = Simple()
print (s.f(1,2))


3

Наследование

Person — хранит общую информацию о людях — имя, профессия, зарплата

Manager — специализированный производный класс

В классе Person мы создадим свою версию для стандартной встроенной функции str, которая есть по умолчанию в любом питоновском классе — для этого она будет иметь префикс с двумя символами подчеркивания слева и справа. Когда мы попытаемся распечатать инстанс класса, будет вызвана str


In [26]:
class Person:
	def __init__(self, name, job=None, pay=0):
		self.name = name
		self.job = job
		self.pay = pay
	def lastName(self):
		return self.name.split()[-1]
	def giveRaise(self, percent):
		self.pay = int(self.pay * (1 + percent))
	def __str__(self):
		return '[Person: %s, %s]' % (self.name, self.pay)

class Manager(Person):
	def __init__(self, name, pay): 
		Person.__init__(self, name, 'mgr', pay) 
	def giveRaise(self, percent, bonus=100):
		Person.giveRaise(self, percent + bonus)

In [28]:
ivan = Person('Иван Petrov')
john = Person('John Sidorov', job='dev', pay=100000)

print(ivan)
print(john)


[Person: Иван Petrov, 0]
[Person: John Sidorov, 100000]

In [30]:
# начисляем премиальные
john.giveRaise(.10)
print(john)


[Person: John Sidorov, 121000]

In [31]:
tom = Manager('Tom Jones', 50000)
tom.giveRaise(.10)
print(tom.lastName())
print(tom)


Jones
[Person: Tom Jones, 5055000]

Полиморфизм

Использование полиморфизма при наследовании классов позволяет переопределять методы суперклассов их подклассами. Например, может возникнуть ситуация, когда все подклассы реализуют определенный метод из суперкласса, и лишь один подкласс должен иметь его другую реализацию. В таком случае метод переопределяется в подклассе. Пример:


In [32]:
class Base:
    def __init__(self,n):
          self.numb = n
    def out(self):
          print (self.numb)
 
class One(Base):
    def multi(self,m):
        self.numb *= m
 
class Two(Base):
    def inlist(self):
          self.inlist = list(str(self.numb))
    def out(self):
        i = 0
        while i < len(self.inlist):
            print (self.inlist[i])
            i += 1
 
obj1 = One(45)
obj2 = Two('abc')
 
obj1.multi(2)
obj1.out() # Вывод числа 90
 
obj2.inlist()
obj2.out() # Вывод в столбик букв a, b, c


90
a
b
c

Задача 1

Напишите программу, запрашивающую у пользователя ввод числа. Если число принадлежит диапазону от -100 до 100, то создается объект одного класса, во всех остальных случаях создается объект другого класса. В обоих классах должен быть метод-конструктор init, который в первом классе возводит число в квадрат, а во-втором - умножает на два.